#import <UIKit/UIKit.h>
#import <CoreGraphics/CGGeometry.h>
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import "MobileStudio/MSAppLauncher.h"
#import "UIFilePickerController/UIFilePickerController.h"

@interface AVPMainViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIFilePickerControllerDelegate>
{
	MPMoviePlayerController	*movieController;
	NSString 		*launchArg;
	UITableView		*recentTable;
	NSMutableArray		*recentFiles;
	UIFilePickerController	*filePicker;
	NSUserDefaults		*defaults;
}
- (void) playMovieAtPath:(NSString *)moviePath;
- (void) movieDidPreload:(NSNotification *)notification;
- (void) movieDidFinishPlayback:(NSNotification *)notification;
- (void) addPathToRecentFiles:(NSString *)filePath;
- (void) clearRecentFiles;
@end

@implementation AVPMainViewController
- (id) init
{
	if ((self = [super init])) [self setTitle:@"AVPlayer"];
	return self;
}

- (UIFilePickerController *) filePicker
{
	return filePicker;
}

- (void) loadView
{
	defaults = [NSUserDefaults standardUserDefaults];

	filePicker = [UIFilePickerController sharedPicker];
	[filePicker setDelegate:self];
	[filePicker setTitle:@"Choose media"];
	[filePicker setPath:NSHomeDirectory()];
	[filePicker setFileTypes:[[defaults objectForKey:@"fileTypes"] componentsSeparatedByString:@" "]];
	
	recentFiles = [defaults objectForKey:@"RecentFiles"];
	
	recentTable = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStyleGrouped];
	[recentTable setDataSource:self];
	[recentTable setDelegate:self];

	[self setView:recentTable];

	launchArg = 	[MSAppLauncher 
				readLaunchInfoArgumentForAppID:@"com.optimo.avplayer" 
				withApplication:[UIApplication sharedApplication]
				deletingLaunchPList:YES
			];

	if([launchArg length] > 0)
	{
		[self addPathToRecentFiles:launchArg];
		[self playMovieAtPath:launchArg];
	}
}

- (void) filePickerCancelled:(UIFilePickerController *)filePicker
{
	[self dismissModalViewControllerAnimated:YES];
}

- (void) filePicker:(UIFilePickerController *)filePicker finishedWithFiles:(NSArray *)selectedFiles
{
	[self dismissModalViewControllerAnimated:YES];
	if(selectedFiles != nil)
	{
		[self playMovieAtPath:[selectedFiles objectAtIndex:0]];
	}
}

- (NSInteger) numberOfSectionsInTableView:(UITableView *)table
{
	if([recentFiles count] > 0)
	{
		return 2;
	}
	else
	{
		return 1;
	}
}

- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
	switch(section)
	{
		case 0 : return 1;
		case 1 : return [recentFiles count]+1;
		default : return 0;
	}
}

- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	switch(section)
	{
		case 0 : return nil;
		case 1 : return @"Recent Files";
		default: return nil;
	}
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
	switch([indexPath section])
	{
		case 0 :
			[cell setText:@"Browse for a file..."];
			break;
		case 1 :
			if([indexPath row] < [recentFiles count])
			{
				[cell setText:[[recentFiles objectAtIndex:[indexPath row]] objectForKey:@"filePath"]];
				[cell setFont:[UIFont boldSystemFontOfSize:[UIFont smallSystemFontSize]]];
				[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
			}
			else
			{
				[cell setText:@"Clear recent files..."];
			}
			[cell setLineBreakMode:UILineBreakModeHeadTruncation];
			break;
	}
	return cell;
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	switch([indexPath section])
	{
		case 0:
			[self presentModalViewController:filePicker animated:YES];
			break;
		case 1:
			if([indexPath row] < [recentFiles count])
			{
				[self playMovieAtPath:[[recentFiles objectAtIndex:[indexPath row]] objectForKey:@"filePath"]];
			}
			else
			{
				[self clearRecentFiles];
			}
			break;
	}
	[recentTable deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:YES];
}

- (void) playMovieAtPath:(NSString *)moviePath
{
	movieController = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];

	[[NSNotificationCenter defaultCenter]
		addObserver:self
		selector:@selector(movieDidPreload:)
		name:MPMoviePlayerContentPreloadDidFinishNotification
		object:movieController
	];

	[[NSNotificationCenter defaultCenter]
		addObserver:self
		selector:@selector(movieDidFinishPlayback:)
		name:MPMoviePlayerPlaybackDidFinishNotification
		object:movieController
	];
}

- (void) movieDidPreload:(NSNotification*)notification
{
	movieController = [notification object];
	NSError *error = [[notification userInfo] objectForKey:@"error"];
	
	if(error == nil)
	{
		[movieController setScalingMode:MPMovieScalingModeAspectFit];
		if([[defaults objectForKey:@"16x9Mode"] boolValue])
		{
			if([movieController respondsToSelector:@selector(videoViewController)])
			{
				[(UIView *)[[movieController videoViewController] videoView] setFrame:CGRectMake(0.0, 24, 480, 272)];
			}
		}
		[self addPathToRecentFiles:[[movieController contentURL] path]];
		[movieController play];
	}
	else
	{	
		NSLog(@"%@", error);
		UIAlertView *movieErrorAlert = 	[[UIAlertView alloc] 
							initWithTitle:@"MediaPlayer Error"
							message:[NSString stringWithFormat:@"%@\n\n%@", [[movieController contentURL] path], [error localizedDescription]]
							delegate:nil
							cancelButtonTitle:@"Dismiss"
							otherButtonTitles:nil
						];
		[movieErrorAlert show];
		[movieErrorAlert release];
	}

	[[NSNotificationCenter defaultCenter]
		removeObserver:self
		name:MPMoviePlayerContentPreloadDidFinishNotification
		object:movieController
	];
}

- (void) movieDidFinishPlayback:(NSNotification*)notification
{
	movieController = [notification object];
	[[NSNotificationCenter defaultCenter]
		removeObserver:self
		name:MPMoviePlayerPlaybackDidFinishNotification
		object:movieController
	];
	[movieController stop];
	[movieController release];
}

- (void) addPathToRecentFiles:(NSString *)filePath
{
	if(recentFiles == nil) recentFiles = [NSMutableArray new];
	
	[recentFiles insertObject:[NSDictionary dictionaryWithObjectsAndKeys:filePath, @"filePath",nil] atIndex:0];
	
	if([recentFiles count] > 1)
	{
		if([(NSString *)[(NSDictionary *)[recentFiles objectAtIndex:1] objectForKey:@"filePath"] isEqualToString:filePath])
		{
			[recentFiles removeObjectAtIndex:0];
		}
	}
	
	if([recentFiles count] >= 16)
		[recentFiles removeLastObject];

	[defaults setObject:recentFiles forKey:@"RecentFiles"];
	[recentTable reloadData];
}

- (void) clearRecentFiles
{
	[recentFiles removeAllObjects];
	[defaults setObject:recentFiles forKey:@"RecentFiles"];
	[recentTable reloadData];
}

- (void) dealloc
{
	[defaults release];
	[movieController dealloc];	
	[launchArg release];
	[recentTable release];	
	[filePicker release];
	[super dealloc];
}

@end	//endimp	AVPMainViewController





@interface AVPConfigViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>
{
	NSUserDefaults		*defaults;
	UITableView		*configTable;
}
- (void) editFileTypes;
- (void) switch16x9:(UISwitch *)switcher;
@end

@implementation AVPConfigViewController
- (id) init
{
	if ((self = [super init])) [self setTitle:@"Config"];
	return self;
}

- (void) loadView
{
	defaults = [NSUserDefaults standardUserDefaults];
	configTable = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStyleGrouped];
	[configTable setDataSource:self];
	[configTable setDelegate:self];
	[self setView:configTable];
	
}

- (NSInteger) numberOfSectionsInTableView:(UITableView *)table
{
		return 2;
}

- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
	switch(section)
	{
		case 0 : return 1;
		case 1 : return 1;
		default : return 0;
	}
}

- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	switch(section)
	{
		case 0 : return @"File Types";
		case 1 : return @"Display";
		default : return nil;
	}
}

- (NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
	switch(section)
	{
		case 1 : return @"This modifies the zoomed-out view for videos that have wide aspect ratio. Off by default.";
		default : return nil;
	}
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];

	switch([indexPath section])
	{
		case 0 :
			[cell setText:([[defaults stringForKey:@"fileTypes"] length] == 0) ? @"All file types" : [defaults stringForKey:@"fileTypes"]];
			[cell setFont:[UIFont boldSystemFontOfSize:[UIFont smallSystemFontSize]]];
			[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
			break;
		case 1 :
			[cell setText:@"16x9 Letterbox Mode"];
			UISwitch *switcher = [[UISwitch alloc] initWithFrame:CGRectMake(200, 8, 60, 26)];
			[switcher addTarget:self action:@selector(switch16x9:) forControlEvents:UIControlEventTouchUpInside];
			[switcher setOn:[defaults integerForKey:@"16x9Mode"]];
			[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
			[[cell contentView] addSubview:switcher];
			[switcher release];
			break;
		default : break;
	}
    return cell;
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	switch([indexPath section])
	{
		case 0 :
			[self editFileTypes];
			break;
		default : break;
	}
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void) editFileTypes
{
	UIAlertView *editAlert = 	[[UIAlertView alloc]
						initWithTitle:@"Edit file types"
						message:@"Enter file types seperated by a space. Leave blank for all types."
						delegate:self
						cancelButtonTitle:@"Cancel"
						otherButtonTitles:@"Save", nil
					];
	[editAlert setTag:9999];
	[editAlert addTextFieldWithValue:[defaults stringForKey:@"fileTypes"] label:@"All file types"];
	[[editAlert textField] becomeFirstResponder];
	[editAlert show];
	[editAlert release];
}
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if ([alertView tag] == 9999)
	{
		NSString *textFieldValue = [[alertView textField] text];
		if (buttonIndex == 0) return;

		if (buttonIndex == 1)
		{
			[defaults setObject:textFieldValue forKey:@"fileTypes"];
			[(UIFilePickerController *)[[[[UIApplication sharedApplication] delegate] mainViewController] filePicker] 
				setFileTypes:[textFieldValue componentsSeparatedByString:@" "]
			];
			[configTable reloadData];
		}
	}
}

- (void) switch16x9:(UISwitch *)switcher
{
	[defaults setInteger:[switcher isOn] forKey:@"16x9Mode"];
}

- (void) dealloc
{
	[defaults release];
	[configTable release];	
	[super dealloc];
}
@end	//endimp AVPMainViewController









@interface AVPAppDelegate : NSObject <UIApplicationDelegate> 
{
	UIWindow		*window;
	UINavigationController 	*navController;
	AVPMainViewController 	*mainViewController;
	AVPConfigViewController *configViewController;
}
- (UINavigationController *) navController;
- (void) pushConfigView;
- (void) showAboutAlert;
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
@end

@implementation AVPAppDelegate
- (AVPMainViewController *) mainViewController;
{
	return mainViewController;
}

- (UINavigationController *) navController;
{
	return navController;
}

- (void) applicationDidFinishLaunching:(UIApplication *)application
{	
	window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	mainViewController = [[AVPMainViewController alloc] init];
	configViewController = [[AVPConfigViewController alloc] init];
	navController = [[UINavigationController alloc] initWithRootViewController:mainViewController];

	UIBarButtonItem *configButton = 	[[UIBarButtonItem alloc] 
							initWithTitle:@"Config" 
							style:UIBarButtonItemStylePlain 
							target:self 
							action:@selector(pushConfigView)
						];

	[[[navController navigationBar] topItem] setLeftBarButtonItem:configButton];
	[configButton release];
	
	UIBarButtonItem *aboutButton =	[[UIBarButtonItem alloc] 
						initWithTitle:@"About" 
						style:UIBarButtonItemStylePlain 
						target:self 
						action:@selector(showAboutAlert)
					];

	[[[navController navigationBar] topItem] setRightBarButtonItem:aboutButton];
	[aboutButton release];

	[window addSubview:[navController view]];
	[window makeKeyAndVisible];
}

- (void) pushConfigView
{
	[navController pushViewController:configViewController animated:YES];
}

- (void) showAboutAlert
{
	UIAlertView *aboutAlert = 	[[UIAlertView alloc]
						initWithTitle:@"AVPlayer 1.1 by Optimo"
						message:@"Plays formats supported by Apple\n\nBuilt with iPhone-GCC"
						delegate:self
						cancelButtonTitle:@"Close"
						otherButtonTitles:nil
					];
	[aboutAlert addButtonWithTitle:@"Visit Website"];
	[aboutAlert show];
	[aboutAlert release];
}

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if(buttonIndex == 1) [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://podshitter.com/apps/avplayer"]];
}

- (void) dealloc
{
	[window release];
	[navController release];
	[mainViewController release];
	[configViewController release];
	[super dealloc];
}

@end	//endimp AVPAppDelegate

int main(int argc, char *argv[])
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	int ret = UIApplicationMain(argc, argv, nil, @"AVPAppDelegate");
	[pool release];
	return ret;
}